#pragma once
#include "Common.h"
#include "GCamera.h"
#include "GTriangle.h"
#include "Texture.h"
#include "Shader.h"

enum XE_DATA_TYPE
{
	emPosition,
	emIndices,
};

struct UI_CONTROL
{
	bool bDrag = false;
	int nLastMousePosX = 0;
	int nLastMousePosY = 0;
};

class GRender
{
public:
	GRender(int nWidth, int nHeight);
	void Init();
	void DrawPixel(int nX, int nY, unsigned int color);
	void Active();
	void Clear();
	void Draw(std::vector<GTriangle*>& lstTriangle);
	static LRESULT ProcessEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
	void	DefaultRender(std::vector<GTriangle*>& lstTriangle);
	int		GetFrameBufferIdx(int nX, int nY); 	// GetPixel Index
	bool	IsInsideTriangle(int nPosX, int nPosY, const Eigen::Vector4f* pVert);
	Eigen::Vector3f ComputeBarycentric2D(float fX, float fY, const Eigen::Vector4f* v);

	Eigen::Matrix4f GetViewPortMatrix();
	Bounds2d CaclBounds(Eigen::Vector4f pArray[], int nNums);
	Eigen::Vector4f Interpolate(float alpha, float beta, float gamma, const Eigen::Vector4f vert1, const Eigen::Vector4f vert2,
		const Eigen::Vector4f vert3, float weight);

	void OnMouseDrag(int nDeltaX, int nDeltaY);
	void OnKeyDown(int nKey);
	GCamera m_Camera;
	int m_nWidth;
	int m_nHeight;
	float* m_pZBuffer;
	std::vector<float> m_zBuffer;
	unsigned int* m_pFrameBuffer;
	HWND m_screenHandle;
	HDC m_screenDc;

	VertexShader*	m_pVertexShader;
	FragmentShader*	m_pFragmentShader;
};

extern GRender* pRender;